package luj.tool.jnproxyan.proxy.network.socks.actor.root.message.admin;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import io.netty.channel.ChannelId;
import io.netty.handler.codec.socksx.SocksVersion;
import io.netty.handler.codec.socksx.v5.Socks5CommandType;
import luj.tool.jnproxyan.proxy.admin.AdminHttpHandler;
import luj.tool.jnproxyan.proxy.admin.http.render.TimeValueRenderer;
import luj.tool.jnproxyan.proxy.network.socks.actor.root.Socks5Actor;
import luj.tool.jnproxyan.proxy.network.socks.request.RequestBody;
import luj.tool.jnproxyan.proxy.network.socks.request.SocksRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static java.util.Comparator.comparing;

@Component
final class OnAdminRequest implements Socks5Actor.Handler<AdminRequestMsg> {

  @Override
  public void onHandle(Context ctx) {
    Socks5Actor self = ctx.getActorState(this);
    AdminRequestMsg msg = ctx.getMessage(this);

    List<?> serverList = self.getRequestMap().values().stream()
        .sorted(comparing(SocksRequest::getReqId).reversed())
        .map(this::makeRow)
        .collect(Collectors.toList());

    Map<String, ?> table = ImmutableMap.of(
        "header", ImmutableList.of("#", "时间", "ver", "method", "cmd", "地址", "状态"),
        "body", serverList
    );

    AdminHttpHandler.Context http = msg.http();
    http.responsePage(ImmutableMap.of(
        "table", http.encodeJson(table)
    ));
  }

  private Map<String, ?> makeRow(SocksRequest req) {
    return ImmutableMap.of(
        "data", renderRequest(req)
//        "account", account.account()
    );
  }

  private List<?> renderRequest(SocksRequest req) {
    Long id = req.getReqId();
    String status = req.getStatus();
    String time = _timeRender.render(req.getBornTime()).substring(5);

    RequestBody body = req.getBody();
    if (body == null) {
      return ImmutableList.of(id.toString(), time, status);
    }

    int ver = body.getVersion().byteValue();
    String method = body.getMethods().toString();
    String cmd = body.getCmd().toString();

    String targetAddr = getTargetAddr(body);
    return ImmutableList.of(id, time, ver, method, cmd, targetAddr, status);
  }

  private String getTargetAddr(RequestBody body) {
    String host = body.getTargetHost();
    if (host == null) {
      return "";
    }
    return body.getTargetHost() + ":" + body.getTargetPort();
  }

  private static final Logger LOG = LoggerFactory.getLogger(OnAdminRequest.class);

  @Autowired
  TimeValueRenderer _timeRender;
}
